package com.erbadagang.springboot.redisdistributedlock;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.annotation.Resource;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Slf4j
@SpringBootApplication
public class RedisDistributedLockApplication implements ApplicationRunner {

    public static void main(String[] args) {
        SpringApplication.run(RedisDistributedLockApplication.class, args);
    }

    /**
     * 直接注入RedissonClient就可以直接使用.
     */
    @Resource
    private RedissonClient redissonClient;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("spring boot run");

        //创建锁
        RLock helloLock = redissonClient.getLock("hello");

        //加锁
        //helloLock.lock(); //会阻塞一直等待锁。
        helloLock.lock(5, TimeUnit.SECONDS);//配置锁失效时长
        try {
            log.info("locked");
            Thread.sleep(1000 * 1);

        } finally {
            //释放锁
            helloLock.unlock();
        }

        String key = "product:001";
        RLock lock = redissonClient.getLock(key);
        try {
            boolean res = lock.tryLock(3, 18, TimeUnit.SECONDS);//设置等待时间和过期时长
            if (res) {
                System.out.println("这里是你的业务代码");
            } else {
                System.out.println("系统繁忙");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

        /**
         * 异步锁
         */
        lock = redissonClient.getLock("erbadagang-lock");
        Future<Boolean> res = null;
        try {
            // lock.lockAsync();
            // lock.lockAsync(100, TimeUnit.SECONDS);
            res = lock.tryLockAsync(3, 100, TimeUnit.SECONDS);
            if (res.get()) {
                System.out.println("这里是你的Async业务代码");
            } else {
                System.out.println("系统繁忙Async");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (res.get()) {
                lock.unlock();
            }
        }
        log.info("finished");
    }


}
